package com.pc.admin.strategy.strategyImpl;

import com.pc.admin.annotation.AutoFrequency;
import com.pc.admin.annotation.Limiting;
import com.pc.admin.entity.FrequencyEntity;
import com.pc.admin.eunms.ErrorEnum;
import com.pc.admin.exception.NoSuchStrategyException;
import com.pc.admin.strategy.FrequencyStrategy;
import com.pc.admin.util.SpElUtils;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.xml.crypto.dsig.SignatureMethod;
import java.lang.reflect.Method;

/**
 * 限流EL 策略
 *
 * @author <a href="https://www.lvfeiy.top">lfy</a>
 * @date 2023/6/23 18:50
 */
@Component
@AutoFrequency
public class ElStrategy extends FrequencyStrategy {
    @Override
    public boolean analysis(Limiting.Target target) {
        return target.equals(Limiting.Target.EL);
    }

    @Override
    public FrequencyEntity service(Limiting limiting, ProceedingJoinPoint joinPoint) {

        return super.asbService(limiting, item -> {


            Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();

            //解析el
            String s = SpElUtils.parseSpEl(method, joinPoint.getArgs(), limiting.spEl());
            //原则上使用el策略不建议在controller层限流，如使用，必须参数不能为空
            if(StringUtils.isBlank(s)){
                throw new NoSuchStrategyException(ErrorEnum.BusinessErrorEnum.El_ERROR);
            }
            //key
            String key = "method_limit_".concat(s);

            item.setKey(key);
            return  item;
        });


    }

    @Override
    public String getName() {
        return "根据  参数el表达式  进行限流";
    }
}
